<template>
    <div class="carousel-wrap">
        <div
            class="carousel-content"
            ref="carousel"
            :style="{transform: `translateX(-${moveX}px)`}"
            @touchstart="handleStart"
            @touchmove="handleMove"
            @touchend="handleEnd"
            @touchcancel="handleEnd"
        >
            <div
                class="carousel-item"
                v-for="(item, index) in renderList"
                :key="index"
            >
                <slot name="content" :value="item"></slot>
            </div>
        </div>
        <div
            v-show="barShow"
            class="carousel-bar"
            ref="scrollBar"
        >
            <div
                class="carousel-point"
                ref="scrollPoint"
                :style="{transform: `translateX(-${barMoveX}px)`}"
            >
            </div>
        </div>
    </div>
</template>

<script>
/**
 * @file mobile multi row and multi column carousel
 */
export default {
    name: 'MobileGroupCarousel',
    props: {
        list: {
            type: Array,
            default: () => []
        },
        row: {
            type: [String, Number],
            default: 2
        },
        col: {
            type: [String, Number],
            default: 2
        }
    },
    computed: {
        renderList() {
            const itemSum = (+this.row) * (+this.col)
            if (this.list.length <= itemSum) {
                return [this.list]
            } else {
                const page = this.list.length / itemSum
                const list = []
                for (let i = 0; i < page; i++) {
                    list[i] = []
                }
                for (let j = 0; j < list.length; j++) {
                    const start = j * itemSum
                    const end = (j + 1) * itemSum
                    list[j] = this.list.slice(start, end)
                }
                return list
            }
        },
        carouselWidth() {
            return this.$refs.carousel.offsetWidth
        },
        maxMoveX() {
            const itemSum = (+this.row) * (+this.col)
            const page = this.list.length / itemSum
            return this.carouselWidth * Math.ceil(page - 1)
        },
        barMaxMoveX() {
            const barWidth = this.$refs.scrollBar.offsetWidth
            const pointWidth = this.$refs.scrollPoint.offsetWidth
            return barWidth - pointWidth
        }
    },
    watch: {
        moveX(nVal) {
            if (nVal > this.maxMoveX) {
                this.moveX = this.maxMoveX
            }
        },
        barMoveX(nVal) {
            if (nVal > this.barMaxMoveX) {
                this.barMoveX = this.barMaxMoveX
            }
            if (nVal < 0) {
                this.barMoveX = 0
            }
        }
    },
    data() {
        return {
            isTouching: false,
            startX: null,
            moveX: 0,
            barMoveX: 0,
            barShow: true
        }
    },
    created() {
        const itemSum = (+this.row) * (+this.col)
        if (this.list.length <= itemSum) {
            this.barShow = false
        }
    },
    methods: {
        handleStart(e) {
            const touches = e.targetTouches[0]
            this.startX = touches.pageX
            this.isTouching = true
        },
        handleMove(e) {
            e.preventDefault();
            if (!this.isTouching) {
                return
            }
            const touches = e.targetTouches[0]
            if (touches.pageX - this.startX < `-${safeDistance}`) {
                this.moveX += this.carouselWidth
            } else if (touches.pageX - this.startX > safeDistance) {
                this.moveX -= this.carouselWidth
            }
            this.isTouching = false
            this.barMoveX = this.moveX * this.barMaxMoveX / this.maxMoveX
        },
        handleEnd() {
            this.isTouching = false
        }
    }
}
</script>

<style lang="less" scoped>
.carousel-wrap {
    overflow: hidden;
    width: 100%;

    .carousel-content {
        display: flex;
        transition: all 0.3s ease;

        .carousel-item {
            display: flex;
            flex-wrap: wrap;
            width: 100%;
            flex-shrink: 0;
        }
    }

    .carousel-bar {
        position: relative;
        width: 120px;
        height: 6px;
        background: #E9EBEF;
        margin: 32px auto 0;

        .carousel-point {
            width: 40px;
            height: 6px;
            background: cornflowerblue;
            position: absolute;
            top: 0;
            left: 0;
            transition: all 0.3s ease;
        }

    }
}
</style>
